#!/usr/bin/perl

#===============================================================================
#     REVISION:  $Id$
#  DESCRIPTION:  Test for Meter::Utils
#===============================================================================

use strict;
use warnings;

use Readonly;
Readonly our $VERSION => qw($Revision$) [1];

use English qw( -no_match_vars );

#use Smart::Comments;

use Test::More tests => 2 + 6 + 5 + 5;
use Test::Exception;

use Meter::Utils qw(
    check_METER_ROOT
    get_action_module_by_action_name
    get_action_name_by_action_module
    check_session_id
    generate_session_id
);

sub test_check_METER_ROOT {    ## no critic (Capitalization)
    lives_ok { check_METER_ROOT() }
    "Check existing METER_ROOT=$ENV{'METER_ROOT'}";

    {
        local $ENV{'METER_ROOT'} = '/no/such';

        throws_ok {
            check_METER_ROOT();
        }
        qr/\QPlease set METER_ROOT environment variable\E/xms,
            "Check invalid METER_ROOT=$ENV{'METER_ROOT'}";
    }

    return;
}

sub _string_or_undef {
    my $str = shift;

    if ( !defined $str ) {
        return 'undef';
    }
    else {
        return qq{'$str'};
    }
}

sub test_get_action_module_by_action_name {
    Readonly my @TEST_CASES => (
        {   action_name   => 'welcome',
            action_module => 'Meter::Action::Welcome',
        },
        {   action_name   => q{},
            action_module => undef,
        },
        {   action_name   => q{a} x 33,
            action_module => undef,
        },
        {   action_name   => '*&$',
            action_module => undef,
        },
        {   action_name   => 'correct_but_no_such_module',
            action_module => undef,
        },
        {   action_name   => undef,
            action_module => undef,
        },
    );

    foreach my $test_case (@TEST_CASES) {
        my $got
            = get_action_module_by_action_name( $test_case->{'action_name'} );
        my $expected = $test_case->{'action_module'};

        is( $got, $expected,
                  'Map action_name -> action_module: '
                . _string_or_undef( $test_case->{'action_name'} ) . ' -> '
                . _string_or_undef( $test_case->{'action_module'} ) );
    }

    return;
}

sub test_get_action_name_by_action_module {
    Readonly my @TEST_CASES => (
        {   action_module => 'Meter::Action::Welcome',
            action_name   => 'welcome',
        },
        {   action_module => 'Foo',
            action_name   => 'foo',
        },
        {   action_module => 'Foo1Bar2Baz3',
            action_name   => 'foo1_bar2_baz3',
        },

        {   action_module => 'AAA',
            action_name   => 'aaa',
        },

        {   action_module => undef,
            action_name   => undef,
        },
    );

    foreach my $test_case (@TEST_CASES) {
        my $got = get_action_name_by_action_module(
            $test_case->{'action_module'} );
        my $expected = $test_case->{'action_name'};

        is( $got, $expected,
                  'Map action_module -> action_name: '
                . _string_or_undef( $test_case->{'action_module'} ) . ' -> '
                . _string_or_undef( $test_case->{'action_name'} ) );
    }

    return;
}

sub test_check_session_id {
    Readonly my @TEST_CASES => (
        {   session_id => generate_session_id(),
            test_label => 'random session_id',
            is_valid   => 1,
        },
        {   session_id => 'a' x 33,
            test_label => 'too long',
            is_valid   => 0,
        },
        {   session_id => 'a' x 31,
            test_label => 'too short',
            is_valid   => 0,
        },
        {   session_id => undef,
            test_label => 'undefined',
            is_valid   => 0,
        },
        {   session_id => q{*} x 32,
            test_label => 'bad symbols',
            is_valid   => 0,
        },
    );

    foreach my $test_case (@TEST_CASES) {
        is( check_session_id( $test_case->{'session_id'} ),
            $test_case->{'is_valid'},
            q{Check that session_id=}
                . _string_or_undef( $test_case->{'session_id'} ) . q{ }
                . ( $test_case->{'is_valid'} ? 'is valid' : 'is NOT valid' )
                . " ($test_case->{'test_label'})"
        );
    }

    return;
}

sub run_tests {
    test_check_METER_ROOT();
    test_get_action_module_by_action_name();
    test_get_action_name_by_action_module();
    test_check_session_id();

    return;
}

run_tests();
